//
//  logger.cpp
//  DemoV2
//
//  Created by 董一龙 on 2022/8/5.
//
#include <thread>
#include <unistd.h>
#include "Logger.hpp"
#include <unistd.h>

FILE* Logger::logFilePtr;
MPSCRingBuffer<1024 * 256> Logger::ringBuffer;
std::string Logger::logFileName;

Logger& Logger::getInstance() {
    static Logger logger;
    return logger;
}

Logger::Logger() {
    if(logFileName.empty()) {
        logFilePtr = fopen("/Users/dongyilong/calltrace.log.json", "w");
    }
    else {
        printf("open log file :%s", logFileName.c_str());
        logFilePtr = fopen(logFileName.c_str(), "w");
    }
    
    // assert(logFilePtr && "打开文件失败");
    // 守护线程
    std::thread(Logger::writeLog).detach();
}

Logger::~Logger() {
    if(logFilePtr) {
        fclose(logFilePtr);
        logFilePtr = NULL;
    }
}
void Logger::syncLog(void const* src, uint32_t bytes) {
    assert(0 && "还没有实现");
}
void Logger::asyncLog(void const* src, uint32_t bytes) {
    while(ringBuffer.write((uint8_t const*)src, bytes) < 0) {
        //std::this_thread::yield();
        usleep(10);
    }
}
void Logger::syncLog(std::string const& msg) {
    syncLog(msg.c_str(), (uint32_t)msg.size());
}

void Logger::asyncLog(std::string const& msg) {
    asyncLog(msg.c_str(), (uint32_t)msg.size());
}

void Logger::writeLog() {
    
    Logger::getInstance();
    
    while(true) {
        static constexpr uint32_t msg_buffer_size = 1024 * 4;
        static char msgBuffer[msg_buffer_size];
        if(logFilePtr == nullptr) {
            std::this_thread::yield();
        }
        uint32_t bytes = ringBuffer.read((uint8_t *)msgBuffer, sizeof(msgBuffer));
        if(logFilePtr && bytes) {
            fwrite(msgBuffer, 1, bytes, Logger::logFilePtr);
            fflush(Logger::logFilePtr);
        }
        else {
            std::this_thread::yield();
        }
    }
}

void Logger::setLogFileName(std::string const& filename) {
    if(logFileName.empty()) {
        logFileName = filename;
    }
}
